home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / lib-tk / turtle.py < prev    next >
Text File  |  2008-10-05  |  27KB  |  958 lines

  1. # LogoMation-like turtle graphics
  2.  
  3. """
  4. Turtle graphics is a popular way for introducing programming to
  5. kids. It was part of the original Logo programming language developed
  6. by Wally Feurzeig and Seymour Papert in 1966.
  7.  
  8. Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
  9. the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
  10. the direction it is facing, drawing a line as it moves. Give it the
  11. command turtle.left(25), and it rotates in-place 25 degrees clockwise.
  12.  
  13. By combining together these and similar commands, intricate shapes and
  14. pictures can easily be drawn.
  15. """
  16.  
  17. from math import * # Also for export
  18. from time import sleep
  19. import Tkinter
  20.  
  21. speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
  22.  
  23. class Error(Exception):
  24.     pass
  25.  
  26. class RawPen:
  27.  
  28.     def __init__(self, canvas):
  29.         self._canvas = canvas
  30.         self._items = []
  31.         self._tracing = 1
  32.         self._arrow = 0
  33.         self._delay = 10     # default delay for drawing
  34.         self._angle = 0.0
  35.         self.degrees()
  36.         self.reset()
  37.  
  38.     def degrees(self, fullcircle=360.0):
  39.         """ Set angle measurement units to degrees.
  40.  
  41.         Example:
  42.         >>> turtle.degrees()
  43.         """
  44.         # Don't try to change _angle if it is 0, because
  45.         # _fullcircle might not be set, yet
  46.         if self._angle:
  47.             self._angle = (self._angle / self._fullcircle) * fullcircle
  48.         self._fullcircle = fullcircle
  49.         self._invradian = pi / (fullcircle * 0.5)
  50.  
  51.     def radians(self):
  52.         """ Set the angle measurement units to radians.
  53.  
  54.         Example:
  55.         >>> turtle.radians()
  56.         """
  57.         self.degrees(2.0*pi)
  58.  
  59.     def reset(self):
  60.         """ Clear the screen, re-center the pen, and set variables to
  61.         the default values.
  62.  
  63.         Example:
  64.         >>> turtle.position()
  65.         [0.0, -22.0]
  66.         >>> turtle.heading()
  67.         100.0
  68.         >>> turtle.reset()
  69.         >>> turtle.position()
  70.         [0.0, 0.0]
  71.         >>> turtle.heading()
  72.         0.0
  73.         """
  74.         canvas = self._canvas
  75.         self._canvas.update()
  76.         width = canvas.winfo_width()
  77.         height = canvas.winfo_height()
  78.         if width <= 1:
  79.             width = canvas['width']
  80.         if height <= 1:
  81.             height = canvas['height']
  82.         self._origin = float(width)/2.0, float(height)/2.0
  83.         self._position = self._origin
  84.         self._angle = 0.0
  85.         self._drawing = 1
  86.         self._width = 1
  87.         self._color = "black"
  88.         self._filling = 0
  89.         self._path = []
  90.         self.clear()
  91.         canvas._root().tkraise()
  92.  
  93.     def clear(self):
  94.         """ Clear the screen. The turtle does not move.
  95.  
  96.         Example:
  97.         >>> turtle.clear()
  98.         """
  99.         self.fill(0)
  100.         canvas = self._canvas
  101.         items = self._items
  102.         self._items = []
  103.         for item in items:
  104.             canvas.delete(item)
  105.         self._delete_turtle()
  106.         self._draw_turtle()
  107.  
  108.     def tracer(self, flag):
  109.         """ Set tracing on if flag is True, and off if it is False.
  110.         Tracing means line are drawn more slowly, with an
  111.         animation of an arrow along the line.
  112.  
  113.         Example:
  114.         >>> turtle.tracer(False)   # turns off Tracer
  115.         """
  116.         self._tracing = flag
  117.         if not self._tracing:
  118.             self._delete_turtle()
  119.         self._draw_turtle()
  120.  
  121.     def forward(self, distance):
  122.         """ Go forward distance steps.
  123.  
  124.         Example:
  125.         >>> turtle.position()
  126.         [0.0, 0.0]
  127.         >>> turtle.forward(25)
  128.         >>> turtle.position()
  129.         [25.0, 0.0]
  130.         >>> turtle.forward(-75)
  131.         >>> turtle.position()
  132.         [-50.0, 0.0]
  133.         """
  134.         x0, y0 = start = self._position
  135.         x1 = x0 + distance * cos(self._angle*self._invradian)
  136.         y1 = y0 - distance * sin(self._angle*self._invradian)
  137.         self._goto(x1, y1)
  138.  
  139.     def backward(self, distance):
  140.         """ Go backwards distance steps.
  141.  
  142.         The turtle's heading does not change.
  143.  
  144.         Example:
  145.         >>> turtle.position()
  146.         [0.0, 0.0]
  147.         >>> turtle.backward(30)
  148.         >>> turtle.position()
  149.         [-30.0, 0.0]
  150.         """
  151.         self.forward(-distance)
  152.  
  153.     def left(self, angle):
  154.         """ Turn left angle units (units are by default degrees,
  155.         but can be set via the degrees() and radians() functions.)
  156.  
  157.         When viewed from above, the turning happens in-place around
  158.         its front tip.
  159.  
  160.         Example:
  161.         >>> turtle.heading()
  162.         22
  163.         >>> turtle.left(45)
  164.         >>> turtle.heading()
  165.         67.0
  166.         """
  167.         self._angle = (self._angle + angle) % self._fullcircle
  168.         self._draw_turtle()
  169.  
  170.     def right(self, angle):
  171.         """ Turn right angle units (units are by default degrees,
  172.         but can be set via the degrees() and radians() functions.)
  173.  
  174.         When viewed from above, the turning happens in-place around
  175.         its front tip.
  176.  
  177.         Example:
  178.         >>> turtle.heading()
  179.         22
  180.         >>> turtle.right(45)
  181.         >>> turtle.heading()
  182.         337.0
  183.         """
  184.         self.left(-angle)
  185.  
  186.     def up(self):
  187.         """ Pull the pen up -- no drawing when moving.
  188.  
  189.         Example:
  190.         >>> turtle.up()
  191.         """
  192.         self._drawing = 0
  193.  
  194.     def down(self):
  195.         """ Put the pen down -- draw when moving.
  196.  
  197.         Example:
  198.         >>> turtle.down()
  199.         """
  200.         self._drawing = 1
  201.  
  202.     def width(self, width):
  203.         """ Set the line to thickness to width.
  204.  
  205.         Example:
  206.         >>> turtle.width(10)
  207.         """
  208.         self._width = float(width)
  209.  
  210.     def color(self, *args):
  211.         """ Set the pen color.
  212.  
  213.         Three input formats are allowed:
  214.  
  215.             color(s)
  216.             s is a Tk specification string, such as "red" or "yellow"
  217.  
  218.             color((r, g, b))
  219.             *a tuple* of r, g, and b, which represent, an RGB color,
  220.             and each of r, g, and b are in the range [0..1]
  221.  
  222.             color(r, g, b)
  223.             r, g, and b represent an RGB color, and each of r, g, and b
  224.             are in the range [0..1]
  225.  
  226.         Example:
  227.  
  228.         >>> turtle.color('brown')
  229.         >>> tup = (0.2, 0.8, 0.55)
  230.         >>> turtle.color(tup)
  231.         >>> turtle.color(0, .5, 0)
  232.         """
  233.         if not args:
  234.             raise Error, "no color arguments"
  235.         if len(args) == 1:
  236.             color = args[0]
  237.             if type(color) == type(""):
  238.                 # Test the color first
  239.                 try:
  240.                     id = self._canvas.create_line(0, 0, 0, 0, fill=color)
  241.                 except Tkinter.TclError:
  242.                     raise Error, "bad color string: %r" % (color,)
  243.                 self._set_color(color)
  244.                 return
  245.             try:
  246.                 r, g, b = color
  247.             except:
  248.                 raise Error, "bad color sequence: %r" % (color,)
  249.         else:
  250.             try:
  251.                 r, g, b = args
  252.             except:
  253.                 raise Error, "bad color arguments: %r" % (args,)
  254.         assert 0 <= r <= 1
  255.         assert 0 <= g <= 1
  256.         assert 0 <= b <= 1
  257.         x = 255.0
  258.         y = 0.5
  259.         self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
  260.  
  261.     def _set_color(self,color):
  262.         self._color = color
  263.         self._draw_turtle()
  264.  
  265.     def write(self, text, move=False):
  266.         """ Write text at the current pen position.
  267.  
  268.         If move is true, the pen is moved to the bottom-right corner
  269.         of the text. By default, move is False.
  270.  
  271.         Example:
  272.         >>> turtle.write('The race is on!')
  273.         >>> turtle.write('Home = (0, 0)', True)
  274.         """
  275.         x, y  = self._position
  276.         x = x-1 # correction -- calibrated for Windows
  277.         item = self._canvas.create_text(x, y,
  278.                                         text=str(text), anchor="sw",
  279.                                         fill=self._color)
  280.         self._items.append(item)
  281.         if move:
  282.             x0, y0, x1, y1 = self._canvas.bbox(item)
  283.             self._goto(x1, y1)
  284.         self._draw_turtle()
  285.  
  286.     def fill(self, flag):
  287.         """ Call fill(1) before drawing the shape you
  288.          want to fill, and fill(0) when done.
  289.  
  290.         Example:
  291.         >>> turtle.fill(1)
  292.         >>> turtle.forward(100)
  293.         >>> turtle.left(90)
  294.         >>> turtle.forward(100)
  295.         >>> turtle.left(90)
  296.         >>> turtle.forward(100)
  297.         >>> turtle.left(90)
  298.         >>> turtle.forward(100)
  299.         >>> turtle.fill(0)
  300.         """
  301.         if self._filling:
  302.             path = tuple(self._path)
  303.             smooth = self._filling < 0
  304.             if len(path) > 2:
  305.                 item = self._canvas._create('polygon', path,
  306.                                             {'fill': self._color,
  307.                                              'smooth': smooth})
  308.                 self._items.append(item)
  309.                 self._canvas.update()
  310.         self._path = []
  311.         self._filling = flag
  312.         if flag:
  313.             self._path.append(self._position)
  314.  
  315.     def begin_fill(self):
  316.         """ Called just before drawing a shape to be filled.
  317.             Must eventually be followed by a corresponding end_fill() call.
  318.             Otherwise it will be ignored.
  319.  
  320.         Example:
  321.         >>> turtle.begin_fill()
  322.         >>> turtle.forward(100)
  323.         >>> turtle.left(90)
  324.         >>> turtle.forward(100)
  325.         >>> turtle.left(90)
  326.         >>> turtle.forward(100)
  327.         >>> turtle.left(90)
  328.         >>> turtle.forward(100)
  329.         >>> turtle.end_fill()
  330.         """
  331.         self._path = [self._position]
  332.         self._filling = 1
  333.  
  334.     def end_fill(self):
  335.         """ Called after drawing a shape to be filled.
  336.  
  337.         Example:
  338.         >>> turtle.begin_fill()
  339.         >>> turtle.forward(100)
  340.         >>> turtle.left(90)
  341.         >>> turtle.forward(100)
  342.         >>> turtle.left(90)
  343.         >>> turtle.forward(100)
  344.         >>> turtle.left(90)
  345.         >>> turtle.forward(100)
  346.         >>> turtle.end_fill()
  347.         """
  348.         self.fill(0)
  349.  
  350.     def circle(self, radius, extent = None):
  351.         """ Draw a circle with given radius.
  352.         The center is radius units left of the turtle; extent
  353.         determines which part of the circle is drawn. If not given,
  354.         the entire circle is drawn.
  355.  
  356.         If extent is not a full circle, one endpoint of the arc is the
  357.         current pen position. The arc is drawn in a counter clockwise
  358.         direction if radius is positive, otherwise in a clockwise
  359.         direction. In the process, the direction of the turtle is
  360.         changed by the amount of the extent.
  361.  
  362.         >>> turtle.circle(50)
  363.         >>> turtle.circle(120, 180)  # half a circle
  364.         """
  365.         if extent is None:
  366.             extent = self._fullcircle
  367.         frac = abs(extent)/self._fullcircle
  368.         steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
  369.         w = 1.0 * extent / steps
  370.         w2 = 0.5 * w
  371.         l = 2.0 * radius * sin(w2*self._invradian)
  372.         if radius < 0:
  373.             l, w, w2 = -l, -w, -w2
  374.         self.left(w2)
  375.         for i in range(steps):
  376.             self.forward(l)
  377.             self.left(w)
  378.         self.right(w2)
  379.  
  380.     def heading(self):
  381.         """ Return the turtle's current heading.
  382.  
  383.         Example:
  384.         >>> turtle.heading()
  385.         67.0
  386.         """
  387.         return self._angle
  388.  
  389.     def setheading(self, angle):
  390.         """ Set the turtle facing the given angle.
  391.  
  392.         Here are some common directions in degrees:
  393.  
  394.            0 - east
  395.           90 - north
  396.          180 - west
  397.          270 - south
  398.  
  399.         Example:
  400.         >>> turtle.setheading(90)
  401.         >>> turtle.heading()
  402.         90
  403.         >>> turtle.setheading(128)
  404.         >>> turtle.heading()
  405.         128
  406.         """
  407.         self._angle = angle
  408.         self._draw_turtle()
  409.  
  410.     def window_width(self):
  411.         """ Returns the width of the turtle window.
  412.  
  413.         Example:
  414.         >>> turtle.window_width()
  415.         640
  416.         """
  417.         width = self._canvas.winfo_width()
  418.         if width <= 1:  # the window isn't managed by a geometry manager
  419.             width = self._canvas['width']
  420.         return width
  421.  
  422.     def window_height(self):
  423.         """ Return the height of the turtle window.
  424.  
  425.         Example:
  426.         >>> turtle.window_height()
  427.         768
  428.         """
  429.         height = self._canvas.winfo_height()
  430.         if height <= 1: # the window isn't managed by a geometry manager
  431.             height = self._canvas['height']
  432.         return height
  433.  
  434.     def position(self):
  435.         """ Return the current (x, y) location of the turtle.
  436.  
  437.         Example:
  438.         >>> turtle.position()
  439.         [0.0, 240.0]
  440.         """
  441.         x0, y0 = self._origin
  442.         x1, y1 = self._position
  443.         return [x1-x0, -y1+y0]
  444.  
  445.     def setx(self, xpos):
  446.         """ Set the turtle's x coordinate to be xpos.
  447.  
  448.         Example:
  449.         >>> turtle.position()
  450.         [10.0, 240.0]
  451.         >>> turtle.setx(10)
  452.         >>> turtle.position()
  453.         [10.0, 240.0]
  454.         """
  455.         x0, y0 = self._origin
  456.         x1, y1 = self._position
  457.         self._goto(x0+xpos, y1)
  458.  
  459.     def sety(self, ypos):
  460.         """ Set the turtle's y coordinate to be ypos.
  461.  
  462.         Example:
  463.         >>> turtle.position()
  464.         [0.0, 0.0]
  465.         >>> turtle.sety(-22)
  466.         >>> turtle.position()
  467.         [0.0, -22.0]
  468.         """
  469.         x0, y0 = self._origin
  470.         x1, y1 = self._position
  471.         self._goto(x1, y0-ypos)
  472.  
  473.     def towards(self, *args):
  474.         """Returs the angle, which corresponds to the line
  475.         from turtle-position to point (x,y).
  476.  
  477.         Argument can be two coordinates or one pair of coordinates
  478.         or a RawPen/Pen instance.
  479.  
  480.         Example:
  481.         >>> turtle.position()
  482.         [10.0, 10.0]
  483.         >>> turtle.towards(0,0)
  484.         225.0
  485.         """
  486.         if len(args) == 2:
  487.             x, y = args
  488.         else:
  489.             arg = args[0]
  490.             if isinstance(arg, RawPen):
  491.                 x, y = arg.position()
  492.             else:
  493.                 x, y = arg
  494.         x0, y0 = self.position()
  495.         dx = x - x0
  496.         dy = y - y0
  497.         return (atan2(dy,dx) / self._invradian) % self._fullcircle
  498.  
  499.     def goto(self, *args):
  500.         """ Go to the given point.
  501.  
  502.         If the pen is down, then a line will be drawn. The turtle's
  503.         orientation does not change.
  504.  
  505.         Two input formats are accepted:
  506.  
  507.            goto(x, y)
  508.            go to point (x, y)
  509.  
  510.            goto((x, y))
  511.            go to point (x, y)
  512.  
  513.         Example:
  514.         >>> turtle.position()
  515.         [0.0, 0.0]
  516.         >>> turtle.goto(50, -45)
  517.         >>> turtle.position()
  518.         [50.0, -45.0]
  519.         """
  520.         if len(args) == 1:
  521.             try:
  522.                 x, y = args[0]
  523.             except:
  524.                 raise Error, "bad point argument: %r" % (args[0],)
  525.         else:
  526.             try:
  527.                 x, y = args
  528.             except:
  529.                 raise Error, "bad coordinates: %r" % (args[0],)
  530.         x0, y0 = self._origin
  531.         self._goto(x0+x, y0-y)
  532.  
  533.     def _goto(self, x1, y1):
  534.         x0, y0 = self._position
  535.         self._position = map(float, (x1, y1))
  536.         if self._filling:
  537.             self._path.append(self._position)
  538.         if self._drawing:
  539.             if self._tracing:
  540.                 dx = float(x1 - x0)
  541.                 dy = float(y1 - y0)
  542.                 distance = hypot(dx, dy)
  543.                 nhops = int(distance)
  544.                 item = self._canvas.create_line(x0, y0, x0, y0,
  545.                                                 width=self._width,
  546.                                                 capstyle="round",
  547.                                                 fill=self._color)
  548.                 try:
  549.                     for i in range(1, 1+nhops):
  550.                         x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
  551.                         self._canvas.coords(item, x0, y0, x, y)
  552.                         self._draw_turtle((x,y))
  553.                         self._canvas.update()
  554.                         self._canvas.after(self._delay)
  555.                     # in case nhops==0
  556.                     self._canvas.coords(item, x0, y0, x1, y1)
  557.                     self._canvas.itemconfigure(item, arrow="none")
  558.                 except Tkinter.TclError:
  559.                     # Probably the window was closed!
  560.                     return
  561.             else:
  562.                 item = self._canvas.create_line(x0, y0, x1, y1,
  563.                                                 width=self._width,
  564.                                                 capstyle="round",
  565.                                                 fill=self._color)
  566.             self._items.append(item)
  567.         self._draw_turtle()
  568.  
  569.     def speed(self, speed):
  570.         """ Set the turtle's speed.
  571.  
  572.         speed must one of these five strings:
  573.  
  574.             'fastest' is a 0 ms delay
  575.             'fast' is a 5 ms delay
  576.             'normal' is a 10 ms delay
  577.             'slow' is a 15 ms delay
  578.             'slowest' is a 20 ms delay
  579.  
  580.          Example:
  581.          >>> turtle.speed('slow')
  582.         """
  583.         try:
  584.             speed = speed.strip().lower()
  585.             self._delay = speeds.index(speed) * 5
  586.         except:
  587.             raise ValueError("%r is not a valid speed. speed must be "
  588.                              "one of %s" % (speed, speeds))
  589.  
  590.  
  591.     def delay(self, delay):
  592.         """ Set the drawing delay in milliseconds.
  593.  
  594.         This is intended to allow finer control of the drawing speed
  595.         than the speed() method
  596.  
  597.         Example:
  598.         >>> turtle.delay(15)
  599.         """
  600.         if int(delay) < 0:
  601.             raise ValueError("delay must be greater than or equal to 0")
  602.         self._delay = int(delay)
  603.  
  604.     def _draw_turtle(self, position=[]):
  605.         if not self._tracing:
  606.             self._canvas.update()
  607.             return
  608.         if position == []:
  609.             position = self._position
  610.         x,y = position
  611.         distance = 8
  612.         dx = distance * cos(self._angle*self._invradian)
  613.         dy = distance * sin(self._angle*self._invradian)
  614.         self._delete_turtle()
  615.         self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
  616.                                           width=self._width,
  617.                                           arrow="last",
  618.                                           capstyle="round",
  619.                                           fill=self._color)
  620.         self._canvas.update()
  621.  
  622.     def _delete_turtle(self):
  623.         if self._arrow != 0:
  624.             self._canvas.delete(self._arrow)
  625.             self._arrow = 0
  626.  
  627.  
  628. _root = None
  629. _canvas = None
  630. _pen = None
  631. _width = 0.50                  # 50% of window width
  632. _height = 0.75                 # 75% of window height
  633. _startx = None
  634. _starty = None
  635. _title = "Turtle Graphics"     # default title
  636.  
  637. class Pen(RawPen):
  638.  
  639.     def __init__(self):
  640.         global _root, _canvas
  641.         if _root is None:
  642.             _root = Tkinter.Tk()
  643.             _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
  644.             _root.title(_title)
  645.  
  646.         if _canvas is None:
  647.             # XXX Should have scroll bars
  648.             _canvas = Tkinter.Canvas(_root, background="white")
  649.             _canvas.pack(expand=1, fill="both")
  650.  
  651.             setup(width=_width, height= _height, startx=_startx, starty=_starty)
  652.  
  653.         RawPen.__init__(self, _canvas)
  654.  
  655.     def _destroy(self):
  656.         global _root, _canvas, _pen
  657.         root = self._canvas._root()
  658.         if root is _root:
  659.             _pen = None
  660.             _root = None
  661.             _canvas = None
  662.         root.destroy()
  663.  
  664. def _getpen():
  665.     global _pen
  666.     if not _pen:
  667.         _pen = Pen()
  668.     return _pen
  669.  
  670. class Turtle(Pen):
  671.     pass
  672.  
  673. """For documentation of the following functions see
  674.    the RawPen methods with the same names
  675. """
  676.  
  677. def degrees(): _getpen().degrees()
  678. def radians(): _getpen().radians()
  679. def reset(): _getpen().reset()
  680. def clear(): _getpen().clear()
  681. def tracer(flag): _getpen().tracer(flag)
  682. def forward(distance): _getpen().forward(distance)
  683. def backward(distance): _getpen().backward(distance)
  684. def left(angle): _getpen().left(angle)
  685. def right(angle): _getpen().right(angle)
  686. def up(): _getpen().up()
  687. def down(): _getpen().down()
  688. def width(width): _getpen().width(width)
  689. def color(*args): _getpen().color(*args)
  690. def write(arg, move=0): _getpen().write(arg, move)
  691. def fill(flag): _getpen().fill(flag)
  692. def begin_fill(): _getpen().begin_fill()
  693. def end_fill(): _getpen().end_fill()
  694. def circle(radius, extent=None): _getpen().circle(radius, extent)
  695. def goto(*args): _getpen().goto(*args)
  696. def heading(): return _getpen().heading()
  697. def setheading(angle): _getpen().setheading(angle)
  698. def position(): return _getpen().position()
  699. def window_width(): return _getpen().window_width()
  700. def window_height(): return _getpen().window_height()
  701. def setx(xpos): _getpen().setx(xpos)
  702. def sety(ypos): _getpen().sety(ypos)
  703. def towards(*args): return _getpen().towards(*args)
  704.  
  705. def done(): _root.mainloop()
  706. def delay(delay): return _getpen().delay(delay)
  707. def speed(speed): return _getpen().speed(speed)
  708.  
  709. for methodname in dir(RawPen):
  710.     """ copies RawPen docstrings to module functions of same name """
  711.     if not methodname.startswith("_"):
  712.         eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
  713.  
  714.  
  715. def setup(**geometry):
  716.     """ Sets the size and position of the main window.
  717.  
  718.     Keywords are width, height, startx and starty:
  719.  
  720.     width: either a size in pixels or a fraction of the screen.
  721.       Default is 50% of screen.
  722.     height: either the height in pixels or a fraction of the screen.
  723.       Default is 75% of screen.
  724.  
  725.     Setting either width or height to None before drawing will force
  726.       use of default geometry as in older versions of turtle.py
  727.  
  728.     startx: starting position in pixels from the left edge of the screen.
  729.       Default is to center window. Setting startx to None is the default
  730.       and centers window horizontally on screen.
  731.  
  732.     starty: starting position in pixels from the top edge of the screen.
  733.       Default is to center window. Setting starty to None is the default
  734.       and centers window vertically on screen.
  735.  
  736.     Examples:
  737.     >>> setup (width=200, height=200, startx=0, starty=0)
  738.  
  739.     sets window to 200x200 pixels, in upper left of screen
  740.  
  741.     >>> setup(width=.75, height=0.5, startx=None, starty=None)
  742.  
  743.     sets window to 75% of screen by 50% of screen and centers
  744.  
  745.     >>> setup(width=None)
  746.  
  747.     forces use of default geometry as in older versions of turtle.py
  748.     """
  749.  
  750.     global _width, _height, _startx, _starty
  751.  
  752.     width = geometry.get('width',_width)
  753.     if width >= 0 or width == None:
  754.         _width = width
  755.     else:
  756.         raise ValueError, "width can not be less than 0"
  757.  
  758.     height = geometry.get('height',_height)
  759.     if height >= 0 or height == None:
  760.         _height = height
  761.     else:
  762.         raise ValueError, "height can not be less than 0"
  763.  
  764.     startx = geometry.get('startx', _startx)
  765.     if startx >= 0 or startx == None:
  766.         _startx = startx
  767.     else:
  768.         raise ValueError, "startx can not be less than 0"
  769.  
  770.     starty = geometry.get('starty', _starty)
  771.     if starty >= 0 or starty == None:
  772.         _starty = starty
  773.     else:
  774.         raise ValueError, "startx can not be less than 0"
  775.  
  776.  
  777.     if _root and _width and _height:
  778.         if 0 < _width <= 1:
  779.             _width = _root.winfo_screenwidth() * +width
  780.         if 0 < _height <= 1:
  781.             _height = _root.winfo_screenheight() * _height
  782.  
  783.         # center window on screen
  784.         if _startx is None:
  785.             _startx = (_root.winfo_screenwidth() - _width) / 2
  786.  
  787.         if _starty is None:
  788.             _starty = (_root.winfo_screenheight() - _height) / 2
  789.  
  790.         _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
  791.  
  792. def title(title):
  793.     """Set the window title.
  794.  
  795.     By default this is set to 'Turtle Graphics'
  796.  
  797.     Example:
  798.     >>> title("My Window")
  799.     """
  800.  
  801.     global _title
  802.     _title = title
  803.  
  804. def demo():
  805.     reset()
  806.     tracer(1)
  807.     up()
  808.     backward(100)
  809.     down()
  810.     # draw 3 squares; the last filled
  811.     width(3)
  812.     for i in range(3):
  813.         if i == 2:
  814.             fill(1)
  815.         for j in range(4):
  816.             forward(20)
  817.             left(90)
  818.         if i == 2:
  819.             color("maroon")
  820.             fill(0)
  821.         up()
  822.         forward(30)
  823.         down()
  824.     width(1)
  825.     color("black")
  826.     # move out of the way
  827.     tracer(0)
  828.     up()
  829.     right(90)
  830.     forward(100)
  831.     right(90)
  832.     forward(100)
  833.     right(180)
  834.     down()
  835.     # some text
  836.     write("startstart", 1)
  837.     write("start", 1)
  838.     color("red")
  839.     # staircase
  840.     for i in range(5):
  841.         forward(20)
  842.         left(90)
  843.         forward(20)
  844.         right(90)
  845.     # filled staircase
  846.     fill(1)
  847.     for i in range(5):
  848.         forward(20)
  849.         left(90)
  850.         forward(20)
  851.         right(90)
  852.     fill(0)
  853.     tracer(1)
  854.     # more text
  855.     write("end")
  856.  
  857. def demo2():
  858.     # exercises some new and improved features
  859.     speed('fast')
  860.     width(3)
  861.  
  862.     # draw a segmented half-circle
  863.     setheading(towards(0,0))
  864.     x,y = position()
  865.     r = (x**2+y**2)**.5/2.0
  866.     right(90)
  867.     pendown = True
  868.     for i in range(18):
  869.         if pendown:
  870.             up()
  871.             pendown = False
  872.         else:
  873.             down()
  874.             pendown = True
  875.         circle(r,10)
  876.     sleep(2)
  877.  
  878.     reset()
  879.     left(90)
  880.  
  881.     # draw a series of triangles
  882.     l = 10
  883.     color("green")
  884.     width(3)
  885.     left(180)
  886.     sp = 5
  887.     for i in range(-2,16):
  888.         if i > 0:
  889.             color(1.0-0.05*i,0,0.05*i)
  890.             fill(1)
  891.             color("green")
  892.         for j in range(3):
  893.             forward(l)
  894.             left(120)
  895.         l += 10
  896.         left(15)
  897.         if sp > 0:
  898.             sp = sp-1
  899.             speed(speeds[sp])
  900.     color(0.25,0,0.75)
  901.     fill(0)
  902.  
  903.     # draw and fill a concave shape
  904.     left(120)
  905.     up()
  906.     forward(70)
  907.     right(30)
  908.     down()
  909.     color("red")
  910.     speed("fastest")
  911.     fill(1)
  912.     for i in range(4):
  913.         circle(50,90)
  914.         right(90)
  915.         forward(30)
  916.         right(90)
  917.     color("yellow")
  918.     fill(0)
  919.     left(90)
  920.     up()
  921.     forward(30)
  922.     down();
  923.  
  924.     color("red")
  925.  
  926.     # create a second turtle and make the original pursue and catch it
  927.     turtle=Turtle()
  928.     turtle.reset()
  929.     turtle.left(90)
  930.     turtle.speed('normal')
  931.     turtle.up()
  932.     turtle.goto(280,40)
  933.     turtle.left(24)
  934.     turtle.down()
  935.     turtle.speed('fast')
  936.     turtle.color("blue")
  937.     turtle.width(2)
  938.     speed('fastest')
  939.  
  940.     # turn default turtle towards new turtle object
  941.     setheading(towards(turtle))
  942.     while ( abs(position()[0]-turtle.position()[0])>4 or
  943.             abs(position()[1]-turtle.position()[1])>4):
  944.         turtle.forward(3.5)
  945.         turtle.left(0.6)
  946.         # turn default turtle towards new turtle object
  947.         setheading(towards(turtle))
  948.         forward(4)
  949.     write("CAUGHT! ", move=True)
  950.  
  951.  
  952.  
  953. if __name__ == '__main__':
  954.     demo()
  955.     sleep(3)
  956.     demo2()
  957.     done()
  958.